import java.util.PriorityQueue;

public class T {

}


class MyTask implements Comparable<MyTask> {
    public Runnable runnable;
    // 为了⽅便后续判定, 使⽤绝对的时间戳.
    public long time;
    public MyTask(Runnable runnable, long delay) {
        this.runnable = runnable;
        // 取当前时刻的时间戳 + delay, 作为该任务实际执⾏的时间戳
        this.time = System.currentTimeMillis() + delay;
    }
    @Override
    public int compareTo(MyTask o) {
        // 这样的写法意味着每次取出的是时间最⼩的元素.
        // 到底是谁减谁?? 俺也记不住!!! 随便写⼀个, 执⾏下, 看看效果~~
        return (int)(this.time - o.time);
    }
}

class MyTimer {
    // 核⼼结构
    private PriorityQueue<MyTask> queue = new PriorityQueue<>();
    // 创建⼀个锁对象
    private Object locker = new Object();
    public void schedule(Runnable command, long after) {
        // 根据参数, 构造 MyTask, 插⼊队列即可.
        synchronized (locker) {
            MyTask myTask = new MyTask(command, after);
            queue.offer(myTask);
            locker.notify();
        }
    }

    // 在这⾥构造线程, 负责执⾏具体任务了.

    public MyTimer() {
        Thread t = new Thread(() -> {
            while (true) {
                try {
                    synchronized (locker) {
                        // 阻塞队列, 只有阻塞的⼊队列和阻塞的出队列, 没有阻塞的查看队⾸元素.
                        while (queue.isEmpty()) {
                            locker.wait();
                        }
                        MyTask myTask = queue.peek();
                        long curTime = System.currentTimeMillis();
                        if (curTime >= myTask.time) {
                            // 时间到了, 可以执⾏任务了
                            queue.poll();
                            myTask.runnable.run();
                        } else {
                            // 时间还没到
                            locker.wait(myTask.time - curTime);
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
    }

}

